#include <string.h>
#include <stdlib.h>

#include "midi_pp.h"
#include "B3_defines.h"
#include "../contrib/libsmf/smf.h"

// free the pointer after use it
B3_event_t*
midi_preprocess(smf_t *smf) {
	unsigned int key_event_count, buf_size;
	unsigned int i, k;
	unsigned char j;
	smf_event_t *event;
	unsigned char* buf;
	B3_event_t temp;
	B3_event_t* ret;
	//count midi events
	key_event_count = 0;
	while((event = smf_get_next_event(smf)) != NULL) {
		buf = smf_event_decode_B3(event);
		if (buf == NULL)
			continue;
		if (buf[0] == 0 || buf[0] == 1)
			key_event_count ++;
		free(buf);
	}
	smf_rewind(smf);
	//create buffer
	buf_size = key_event_count * 9 + 1;
	ret = malloc(sizeof(B3_event_t)*buf_size);
	//fill the buffer
	i=0;
	while((event = smf_get_next_event(smf)) != NULL) {
		buf = smf_event_decode_B3(event);
		if (buf == NULL)
			continue;
		if (buf[0] == 0 || buf[0] == 1) {
			//for each note, gen DRAWBAR_NUM events
			for (j=1; j<=DRAWBAR_NUM; j++) {
				ret[i].time_seconds = event->time_seconds + (j-1)*CONTACT_PERIOD;
				ret[i].type = buf[0];
				ret[i].track = buf[1];
				ret[i].velocity = buf[3];
				ret[i].note = buf[2];
				ret[i].contact = j;
				i++;
			}
		}
		free(buf);
	}
	//sort the buffer
	for (k=1; k<buf_size-1; k++) {
		for (i=buf_size-2; i>=k; --i) {
			if (ret[i-1].time_seconds > ret[i].time_seconds) {
				memcpy(&temp, ret+i-1, sizeof(B3_event_t));
				memcpy(ret+i-1, ret+i, sizeof(B3_event_t));
				memcpy(ret+i, &temp, sizeof(B3_event_t));
			}
		}
	}
	//add a tail to buf
	ret[buf_size-1].type = 0xFF;
	//FIXME for test
	for (i=0; i<25; i++) {
		printf("%f, %d, %d, %d, %d, %d\n", ret[i].time_seconds, ret[i].type, ret[i].track, ret[i].note, ret[i].velocity, ret[i].contact);
	}
	//return the buffer
	return ret;
}
